package com.aries.ui.widget.progress;

import com.aries.ui.util.AttrUtils;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;

/**
 * @Author: AriesHoo on 2018/7/19 10:40
 * @E-Mail: AriesHoo@126.com
 * Function: 自定义Material Design 风格ProgressBar
 * Description:
 * 1、2017-11-15 09:39:17 AriesHoo增加是否圆角属性控制
 */
public class MaterialProgressBar extends ComponentContainer implements Component.DrawTask {

    private static float DEFAULT_MAX_ANGLE = -305f;
    private static float DEFAULT_MIN_ANGLE = -0f;

    private AnimatorGroup animatorSet;
    private Paint arcPaint;
    private RectFloat arcRect;
    private float startAngle = -45f;
    private float sweepAngle = -15f;
    private float incrementAngele = 0;
    private int size;

    private int arcColor;
    private float borderWidth = 6;
    /**
     * 最小300(600与5.0以上接近),最大建议不超过1000
     */
    private int duration = 800;
    private boolean mRoundEnable = true;

    public MaterialProgressBar(Context context) {
        this(context, null, "");
    }

    public MaterialProgressBar(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public MaterialProgressBar(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttribute(context, attrs);
        addDrawTask(this);
    }

    private void initAttribute(Context context, AttrSet attrs) {
//        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MaterialProgressBar, defStyle, 0);
        arcColor =  AttrUtils.getColorFromAttr(attrs,"materialProgressBar_progress_arcColor",Color.BLUE.getValue());
//        arcColor = typedArray.getColor(R.styleable.MaterialProgressBar_progress_arcColor, Color.BLUE);
        borderWidth =  AttrUtils.getDimensionFromAttr(attrs,"materialProgressBar_progress_borderWidth", (int) vp2px(3));
//        borderWidth = typedArray.getDimensionPixelSize(R.styleable.MaterialProgressBar_progress_borderWidth, vp2px(3));
        duration = AttrUtils.getIntegerFromAttr(attrs,"materialProgressBar_progress_duration", duration);
//        duration = typedArray.getInt(R.styleable.MaterialProgressBar_progress_duration, duration);
        mRoundEnable = AttrUtils.getBooleanFromAttr(attrs,"materialProgressBar_progress_roundEnable", false);
//        mRoundEnable = typedArray.getBoolean(R.styleable.MaterialProgressBar_progress_roundEnable, false);
//        typedArray.recycle();
        init();
        setViewAttributes();
    }

    private void init() {
        arcPaint = new Paint();
        arcPaint.setColor(new Color(arcColor));
        arcPaint.setStrokeWidth(borderWidth);
        arcPaint.setAntiAlias(true);
        arcPaint.setStyle(Paint.Style.STROKE_STYLE);
        arcRect = new RectFloat();

        setArrangeListener(new ArrangeListener() {
            @Override
            public boolean onArrange(int i, int i1, int i2, int i3) {
                int w = i2 - i;
                int h = i3 - i1;
                size = Math.min(w, h);
                startBound();
                return false;
            }
        });
    }

    private void setViewAttributes() {
        setArcColor(new Color(arcColor));
        setBorderWidth(borderWidth);
        setDuration(duration);
        setRoundEnable(mRoundEnable);
    }

    /**
     * 设置颜色
     *
     * @param color  color
     * @return  MaterialProgressBar
     */
    public MaterialProgressBar setArcColor(Color color) {
        this.arcColor = color.getValue();
        arcPaint.setColor(new Color(arcColor));
        return this;
    }

    /**
     * 设置粗细
     *
     * @param width  width
     * @return  MaterialProgressBar
     */
    public MaterialProgressBar setBorderWidth(float width) {
        this.borderWidth = width;
        arcPaint.setStrokeWidth(borderWidth);
        return this;
    }

    /**
     * 设置循环动画延迟
     *
     * @param duration 动画延迟
     * @return  MaterialProgressBar
     */
    public MaterialProgressBar setDuration(int duration) {
        if (duration < 300) {
            duration = 300;
        }
        this.duration = duration;
        return this;
    }

    /**
     * 设置是否圆角
     *
     * @param enable  是否圆角
     * @return  MaterialProgressBar
     */
    public MaterialProgressBar setRoundEnable(boolean enable) {
        this.mRoundEnable = enable;
        arcPaint.setStrokeCap(mRoundEnable ? Paint.StrokeCap.ROUND_CAP : Paint.StrokeCap.SQUARE_CAP);
        return this;
    }

    private void startBound() {
        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        arcRect.fuse((float) (paddingLeft + (double)borderWidth), (float) (paddingTop + (double)borderWidth), (float) (size - paddingLeft - (double)borderWidth), (float) (size - paddingTop - (double)borderWidth));
    }

    private void startAnimation() {
        if (animatorSet != null && animatorSet.isRunning()) {
            animatorSet.cancel();
        }
        animatorSet = new AnimatorGroup();
        AnimatorGroup set = getAnimator();
        animatorSet.runParallel(set);
        animatorSet.setStateChangedListener(new Animator.StateChangedListener() {
            private boolean isCancel = false;
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {
                isCancel = true;
            }

            @Override
            public void onEnd(Animator animator) {
                if (!isCancel) {
                    startAnimation();
                }
                tempAngle1 = -1;
                tempAngle2 = -1;
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        });
//        animatorSet.addListener(new AnimatorListener() {
//            private boolean isCancel = false;
//
//            @Override
//            public void onAnimationStart(Animator animation) {
//            }
//
//            @Override
//            public void onAnimationRepeat(Animator animation) {
//            }
//
//            @Override
//            public void onAnimationEnd(Animator animation) {
//                if (!isCancel) {
//                    startAnimation();
//                }
//            }
//
//            @Override
//            public void onAnimationCancel(Animator animation) {
//                isCancel = true;
//            }
//        });
        animatorSet.start();
    }

    private float tempAngle1 = -1;
    private float tempAngle2 = -1;

    /**
     * 循环的动画
     *
     * @return  AnimatorGroup
     */
    private AnimatorGroup getAnimator() {
        //从小圈到大圈
//        AnimatorValue holdAnimator1 = ValueAnimator.ofFloat(incrementAngele + DEFAULT_MIN_ANGLE, incrementAngele + 115f);
        AnimatorValue holdAnimator1 = new AnimatorValue();
        holdAnimator1.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                if(tempAngle1 == -1){
                    tempAngle1 = incrementAngele;
                }
                incrementAngele = (float) ((double)tempAngle1 + (double)DEFAULT_MIN_ANGLE + (double)v * 115d - (double)v * (double)DEFAULT_MIN_ANGLE);
                invalidate();
            }
        });
        holdAnimator1.setDuration(duration);
        AnimatorValue expandAnimator =new AnimatorValue();
        expandAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                sweepAngle = (float) ((double)DEFAULT_MIN_ANGLE + (double)v * (double)DEFAULT_MAX_ANGLE - (double)v * (double)DEFAULT_MIN_ANGLE);
                incrementAngele -= (double)sweepAngle;
                invalidate();
            }
        });
        expandAnimator.setDuration(duration);


        AnimatorValue holdAnimator = new AnimatorValue();
        holdAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                if(tempAngle2 == -1){
                    tempAngle2 = startAngle;
                }
                startAngle = (float) ((double)tempAngle2 + (double)v * (double)115f - (double)v * (double)DEFAULT_MIN_ANGLE);
                invalidate();
            }
        });

        holdAnimator.setDuration(duration);
        AnimatorValue narrowAnimator = new AnimatorValue();
        narrowAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                sweepAngle = (float) ((double)DEFAULT_MAX_ANGLE + (double)v * (double)DEFAULT_MIN_ANGLE - (double)v * (double)DEFAULT_MAX_ANGLE);
                invalidate();
            }
        });

        narrowAnimator.setDuration(duration);

        AnimatorGroup set = new AnimatorGroup();
        set.build().addAnimators(holdAnimator1,expandAnimator);
        set.build().addAnimators(holdAnimator1,holdAnimator,narrowAnimator);
        return set;
    }

    public float vp2px(float vp) {
        Display display = DisplayManager.getInstance().getDefaultDisplay(mContext).get();
        float dpi = display.getAttributes().densityPixels;
        return (float) ((double)vp * (double)dpi + 0.5d * (vp >= 0 ? 1 : -1));
    }

    @Override
    public void addDrawTask(DrawTask task) {
        super.addDrawTask(task);
        task.onDraw(this, mCanvasForTaskOverContent);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.drawArc(arcRect, new Arc((float) ((double)startAngle + (double)incrementAngele), sweepAngle, false), arcPaint);
        if (animatorSet == null || !animatorSet.isRunning()) {
            startAnimation();
        }
    }
}
